package centerberg.engine;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.geom.AffineTransform;
import java.awt.image.ImageObserver;

/**
 * A texture that is drawable by a render.
 * 
 * @author Andreas
 */
public class Texture implements ImageObserver
{
    public enum Type {
        NORMAL, SCALED, TILED;
    }
    
    protected Image           image;
    protected Dimension       size;
    protected AffineTransform transform;
    
    /**
     * Creates a new texture from the given image.
     * 
     * @param image the image
     */
    Texture(Image image)
    {
        this(image, 0, 0);
    }
    
    /**
     * Creates a new texture from the given image of the specified dimension.
     * If no dimension is given it will be the size of the image itself.
     * 
     * @param image the image
     * @param w     the width of the texture
     * @param h     the height of the texture
     */
    public Texture(Image image, int w, int h)
    {
        this.image = image;
        this.transform = new AffineTransform();
        
        if (w == 0 || h == 0)
            this.size = new Dimension(image.getWidth(this), image.getHeight(this));
        else
            this.size = new Dimension(w, h);
    }
    
    /**
     * Returns the image for this texture for drawing.
     * 
     * @return the image
     */
    public Image getImage()
    {
        return image;
    }
    
    /**
     * Returns the size of the texture.
     * 
     * @return the size of the texture
     */
    public Dimension getSize()
    {
        return size;
    }
    
    /**
     * Returns the current transformation for the image.
     * Internal use by the render.
     * 
     * @return the current transformation
     */
    AffineTransform getTransform()
    {
        return transform;
    }
    
    /**
     * Sets this textures position to the given coordinates.
     * 
     * @param x the x-coordinate
     * @param y the y-coordinate
     */
    public void setPosition(double x, double y)
    {
        translate(x-transform.getTranslateX(), y-transform.getTranslateY());
    }
    
    /**
     * Shears the transform. Should usually not be called except when creating
     * the texture. If you do call it make sure to update the physical
     * transformation if the texture is associated with a physics object.
     * 
     * @param shy the shear
     */
    public void shear(double shy)
    {
        transform.shear(0, shy);
    }
    
    /**
     * Moves the texture.
     * 
     * @param dx
     * @param dy 
     */
    public void translate(double dx, double dy)
    {
        transform.translate(dx, dy);
    }
    
    public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
    {
        if ((infoflags & HEIGHT) != 0)
            size.height = height;
        if ((infoflags & WIDTH) != 0)
            size.width = width;
        
        return size.width == 0 || size.height == 0;
    }
}
